/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package simulator;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.vecmath.Color3f;
import javax.vecmath.Vector3f;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import simulator.ObjectInterface.ObjectException;
import simulator.XMLParser.XMLParserException;

/**
 *
 * @author vdelaitr
 */
public abstract class World {
    // Lights in the world
    public class Light {
        Color3f color;
        Vector3f direction;

        Light(Color3f c, Vector3f d) {
            color = c;
            direction = d;
        }
    }
    private List<Light> lights;

    // Objects in the world
    private CompoundObject worldObjects;

    // One exeption for the class World
    public static class WorldException extends Exception {
        WorldException(String message) {
            super(message);
        }
    }

    // Load the file world.xml
    public World(String file) throws WorldException {
        parseXML(file);
    }

    public List<Light> getLights() {
            return lights;
    }

    // Parse XML file
    private void parseXML(String path) throws WorldException {
        worldObjects = null;

        // Open XML parser
        SAXBuilder sxb = new SAXBuilder();

        try {
            // Open file
            Element root = sxb.build(new File(path)).getRootElement();
            if(root != null) {              
                Iterator itr = (root.getChildren()).iterator();
                while(itr.hasNext()) {
                    Element e = (Element)itr.next();
                    String tag = e.getName();
                    if (tag.equals("light")) {
                        parseLight(e);
                    }
                    else if (tag.equals("objects")) {
                        if (worldObjects == null) {
                            worldObjects = CompoundObject.parse(e);
                        }
                        else {
                            throw new WorldException("Only one \"object\" tag allowed for world.");
                        }
                    }
                    else {
                        throw new WorldException("Unknown tag :" + tag);
                    }
                }
            }
            else {
                throw new WorldException("Bad XML file for world description.");
            }
        }
        catch(XMLParserException e) {
            throw new WorldException("XMLParserException : " + e.getMessage());
        }
        catch(ObjectException e) {
            throw new WorldException("ObjectException : " + e.getMessage());
        }
        catch(JDOMException e) {
            throw new WorldException("JDOMException : " + e.getMessage());
        }
        catch(IOException e) {
            throw new WorldException("IOException : " + e.getMessage());
        }

        if (worldObjects == null) {
            throw new WorldException("Could not find \"object\" tag for world.");
        }
    }

    // Parse XML for a light source
    private void parseLight(Element root) throws WorldException, XMLParserException {
        Color3f color = null;
        Vector3f direction = null;
        
        Iterator itr = (root.getChildren()).iterator();
        while(itr.hasNext()) {
            Element e = (Element)itr.next();
            String tag = e.getName();
            if (tag.equals("color")) {
                color = XMLParser.parseColor(e);
            }
            else if (tag.equals("direction")) {
                direction = XMLParser.parseVector(e);
            }           
            else {
                throw new WorldException("Unknown tag :" + tag);
            }
        }

        lights.add(new Light(color, direction));
    }
}
